import React from 'react';
import {Dimensions, Platform, ScrollView, StyleSheet} from 'react-native';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as profileActionCreator from '../../actions/profile-actions';
import ListItem from '../../components/list-item';
import {getRealSize, RequestCameraPermission} from '../../utils';
import InputDialog from '../../components/input-dialog';
import Toast from '../../components/toast';
import * as RNImagePicker from 'react-native-image-picker';
import {connectActionSheet} from '@expo/react-native-action-sheet';
import config from '../../../config.json';
import {UploadState} from '../../components/file-upload';
import {v4 as uuid} from 'uuid';
import RNFS from 'react-native-fs';
import {I18n} from '../../reducers/intl';
import {UserType} from '../../reducers/user';
import {isNumber} from '../../commons/validate';
const rules = {
  mobile: {
    validator: (rule, value, callback, source) => {
      if (!value || isNumber(value)) {
        return callback();
      }
      callback(new Error(I18n.t('form.validate.message.mobile')));
    },
  },
  tel: {
    validator: (rule, value, callback, source) => {
      if (!value || isNumber(value)) {
        return callback();
      }
      callback(new Error(I18n.t('form.validate.message.mobile')));
    },
  },
};

class ProfileScreen extends React.PureComponent {
  static navigationOptions = () => ({
    headerBackTitleStyle: Platform.OS === 'ios' && {
      height: 0,
      width: 0,
    },
    title: I18n.t('page.title.profile'),
  });

  constructor(props) {
    super(props);
    this.state = {
      allowSubmit: true,
      errors: [],
    };
  }

  onSubmit = value => {
    const {profileActions, user} = this.props;
    const payload = {[this.state.field]: value};
    profileActions.submit(payload, user.type);
    this.setState({dialogVisible: false});
  };

  onChangeValue = async (value, field) => {
    const {profileActions} = this.props;
    profileActions.update({[field]: value});
  };

  onChangeAvatar = () => {
    this.props.showActionSheetWithOptions(
      {
        options: this.props.imageOptions,
        cancelButtonIndex: 2,
        destructiveButtonIndex: 2,
        textStyle: {flex: 1},
      },
      index => this.onShowPick(index),
    );
  };

  onShowPick = async index => {
    const upload = this.upload;
    try {
      await RequestCameraPermission();
    } catch (e) {
      return Toast.show(e.message);
    }
    if (index === 0) {
      RNImagePicker.launchCamera(
        {
          mediaType: 'photo',
          includeBase64: false,
          maxHeight: Dimensions.get('screen').height,
          maxWidth: Dimensions.get('screen').width,
        },
        upload,
      );
    } else if (index === 1) {
      RNImagePicker.launchImageLibrary(
        {
          mediaType: 'photo',
          includeBase64: false,
          maxHeight: Dimensions.get('screen').height,
          maxWidth: Dimensions.get('screen').width,
        },
        upload,
      );
    }
  };

  upload = response => {
    const {token, profileActions, user} = this.props;
    const {avatar = {}} = user;
    // console.log(response);
    if (response.errorCode === 'permission') {
      return Toast.show(I18n.t('toast.noPermission'));
    }

    if (response.didCancel) {
      return;
    }
    const url = `${config.httpClient.host}/web/image/new`;
    const filepath = Platform.select({
      android: response.uri.replace('file://', ''),
      ios: response.uri.replace('file://', ''),
    });
    // {
    //   "fileName": "rn_image_picker_lib_temp_d25c7647-f2a5-48a0-9582-8c0690347bc6.jpg",
    //     "fileSize": 93393,
    //     "height": 293,
    //     "type": "image/jpeg",
    //     "uri": "file:///data/user/0/com.molarapp/cache/rn_image_picker_lib_temp_d25c7647-f2a5-48a0-9582-8c0690347bc6.jpg",
    //     "width": 392
    // }
    const uploadFile = {
      state: UploadState.PENDING,
      name: 'file',
      filename: response.name,
      filepath,
      filetype: response.type,
    };
    // console.log(url, token.access, uploadFile);
    const uid = uuid();
    uploadFile.uid = uid;
    const {jobId, promise} = RNFS.uploadFiles({
      toUrl: url,
      files: [uploadFile],
      fields: {file: 'file'},
      binaryStreamOnly: false,
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token.access}`,
      },
      beginCallback: jobId => {
        profileActions.update({
          avatar: {
            ...avatar,
            jobId,
            rate: 0,
            state: UploadState.PENDING,
          },
        });
      },
      progressCallback: response => {
        const percentage = Math.floor(
          (response.totalBytesSent / response.totalBytesExpectedToSend) * 100,
        );
        if (percentage % 20 === 0) {
          profileActions.update({
            avatar: {
              ...avatar,
              jobId: response.jobId,
              rate: percentage,
              state: UploadState.UPLOADING,
            },
          });
        }
      },
    });

    profileActions.update({
      avatar: {
        ...avatar,
        ...uploadFile,
        jobId,
        state: UploadState.PENDING,
      },
    });

    promise
      .then(response => {
        //HTTP response响应
        if (response.statusCode == 200) {
          console.log('FILES UPLOADED!'); // response.statusCode状态码, response.headers响应header, response.body 响应body
          const payload = JSON.parse(response.body);
          profileActions.update({
            avatar: {
              ...avatar,
              ...payload.data,
              jobId,
              state: UploadState.DONE,
            },
          });
          profileActions.submit(
            {
              avatar: payload.data.id,
            },
            user.type,
          );
        } else {
          console.log('SERVER ERROR', response);
        }
      })
      .catch(err => {
        //HTTP请求异常
        if (err.description === 'cancelled') {
          // cancelled by user
        }
        console.log(err);
      });
  };

  render() {
    const {user, navigation} = this.props;
    const name = user.clinic_name || user.vendor_name || '';
    const value = user[this.state.field];
    return (
      <ScrollView style={Styles.container}>
        <ListItem
          label={I18n.t('form.label.avatar')}
          avatar={user.avatar || {}}
          onPress={this.onChangeAvatar}
        />
        <ListItem
          label={I18n.t('form.label.name')}
          extra={name || I18n.t('form.label.name')}
          onPress={() =>
            this.setState({
              dialogVisible: true,
              field: [UserType.dentist, UserType.clinic].includes(user.type)
                ? 'clinic_name'
                : 'vendor_name',
            })
          }
        />
        <ListItem
          label={I18n.t('form.label.tel')}
          extra={user.tel}
          onPress={() => this.setState({dialogVisible: true, field: 'tel'})}
        />
        <ListItem label={I18n.t('form.label.email')} extra={user.email} />
        <ListItem
          label={I18n.t('form.label.mobile')}
          extra={user.mobile}
          onPress={() => this.setState({dialogVisible: true, field: 'mobile'})}
        />
        {[UserType.dentist, UserType.clinic].includes(user.type) && (
          <React.Fragment>
            <ListItem
              label={I18n.t('form.label.facebook')}
              extra={user.facebook}
              onPress={() =>
                this.setState({dialogVisible: true, field: 'facebook'})
              }
            />
            <ListItem
              label={I18n.t('form.label.wechat')}
              extra={user.wechat}
              onPress={() =>
                this.setState({dialogVisible: true, field: 'wechat'})
              }
            />
            <ListItem
              label={I18n.t('form.label.whatsapp')}
              extra={user.whatsapp}
              onPress={() =>
                this.setState({dialogVisible: true, field: 'whatsapp'})
              }
            />
          </React.Fragment>
        )}
        <ListItem
          label={I18n.t('form.label.country')}
          extra={user.country}
          onPress={() => navigation.navigate('Location')}
        />
        <ListItem
          label={I18n.t('form.label.address_1')}
          extra={user.address_1}
          onPress={() => navigation.navigate('Location')}
        />
        <InputDialog
          visible={this.state.dialogVisible}
          defaultValue={value}
          rules={rules}
          field={this.state.field}
          cancelLabel={I18n.t('button.close')}
          okLabel={I18n.t('button.save')}
          placeholder={value || I18n.t(`form.label.${this.state.field}`)}
          onClose={() => this.setState({dialogVisible: false})}
          onSubmit={value => this.onSubmit(value)}
        />
      </ScrollView>
    );
  }
}

const mapStateToProps = state => ({
  appState: state.appState,
  user: state.user,
  token: state.token,
  imageOptions: [
    I18n.t('options.image.camera'),
    I18n.t('options.image.album'),
    I18n.t('options.image.close'),
  ],
});

const mapDispatchToProps = dispatch => ({
  profileActions: bindActionCreators(profileActionCreator, dispatch),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(connectActionSheet(ProfileScreen));

const Styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingHorizontal: getRealSize(15),
  },
});
